#ifndef COLETORPCP_H
#define COLETORPCP_H

#include <QObject>
#include <QString>
#include <QList>
#include "utils/cache.h"
#include "utils/conf.h"
#include "db/db.h"

#include "dao/dao.h"
#include "dao/departamentodao.h"
#include "dao/operacaodao.h"
#include "dao/produtodao.h"
#include "dao/panelasdao.h"
#include "backgroundworker.h"

#include <unistd.h>

#include "utils/log.h"

//#define NETWORK_INTERFACE_NAME "eth0"
#define NETWORK_INTERFACE_NAME "wlan0"

//#define CONF_FILE_NAME "/home/pcp/coletor_pcp.conf"
#define CONF_FILE_NAME "/root/qtprojects/coletor_pcp.conf"

//#define VERSION_FILE_NAME "/home/pcp/version.info"
#define VERSION_FILE_NAME "/root/version.info"

#define OPERACOES_POR_PAGINA 12
#define PRODUTOS_POR_PAGINA 24
#define PANELAS_POR_PAGINA 9

#define KEY_DEPARTAMENTO "departamento"
#define KEY_OPERACOES "operacoes"
#define KEY_PRODUTOS_PREFFIX "produtos_"
#define KEY_PANELAS "panelas"

#define FILTRO_TODOS "Todos"

class PluginWorker;

class ColetorPCP : public QObject
{
    Q_OBJECT
    Q_PROPERTY(Conf* conf READ conf WRITE setConf NOTIFY confChanged)
public:
    explicit ColetorPCP(QObject *parent = 0);
    ~ColetorPCP();

    Conf* conf();
    void setConf(Conf *conf);

    Q_INVOKABLE void load_all_data();

    Q_INVOKABLE void testar_rede();
    Q_INVOKABLE void testar_bd();
    Q_INVOKABLE void desligar();

    Q_INVOKABLE QString get_plataforma();
    Q_INVOKABLE QString get_departamento();
    Q_INVOKABLE QString get_version();

    Q_INVOKABLE QList<QObject *> get_operacoes(int numero_pagina = 0);
    Q_INVOKABLE int get_total_paginas_operacoes();

    Q_INVOKABLE QList<QObject *> get_produtos(QString filtro, int numero_pagina=0);
    Q_INVOKABLE int get_total_paginas_produtos(QString filtro);

    Q_INVOKABLE QList<QObject *> get_panelas(int numero_pagina=0);
    Q_INVOKABLE int get_total_paginas_panelas();

    Q_INVOKABLE QString interface_type();

    Q_INVOKABLE void on_exit();

    void reloadTouchPlugin();

    void doNetworkTest();
    void doDatabaseTest();
    void doLoadAllData();
    void doShutdown();


signals:
    void confChanged();

    void networkError(QString mensagem);
    void networkSuccess();

    void databaseConnectionError(QString mensagem);
    void databaseConnectionSuccess();

    void databaseError(QString mensagem);
    void dataLoaded();

private:
    DB *db;
    Cache *cache;
    Conf *m_conf;
    DepartamentoDAO *departamentoDAO;
    OperacaoDAO *operacaoDAO;
    ProdutoDAO *produtoDAO;
    PanelaDAO *panelaDAO;
    QThread backgroundWorkerThread;

    PluginWorker *pluginWorker;
    QThread pluginWorkerThread;

    QList<QObject*> getListFromCache(QString cacheKey, int numeroPagina, int pageSize);
    int numPaginas(int count, int pageSize);
    QList<QObject*> subList(QList<QObject*> list, int begin, int count);
};

class ColetorWorker: public BackgroundWorker
{
    Q_OBJECT

public:
    explicit ColetorWorker(QObject *parent, ColetorPCP *coletor)
        : BackgroundWorker(parent)
    {
        LOGD("BEGIN");
        this->coletor = coletor;
        LOGD("END");
    }

signals:

public slots:
    void doNetworkTest() {
        LOGD("BEGIN");
        coletor->doNetworkTest();
        this->deleteLater();
        LOGD("END");
    }

    void doDatabaseTest() {
        LOGD("BEGIN");
        coletor->doDatabaseTest();
        this->deleteLater();
        LOGD("END");
    }

    void doLoadAllData() {
        LOGD("BEGIN");
        coletor->doLoadAllData();
        this->deleteLater();
        LOGD("END");
    }

    void doShutdown() {
        LOGD("BEGIN");
        coletor->doShutdown();
        this->deleteLater();
        LOGD("END");
    }

private:
    ColetorPCP *coletor;
};

class PluginWorker: public BackgroundWorker
{
    Q_OBJECT

public:
    explicit PluginWorker(QObject *parent, ColetorPCP *coletor)
        : BackgroundWorker(parent)
    {
        LOGD("BEGIN");
        this->coletor = coletor;
        running = true;
        LOGD("END");
    }

    void stop() {
        LOGD("BEGIN");
        running = false;
        LOGD("END");
    }

signals:

public slots:
    void doPluginReload() {
        LOGD("BEGIN");
        while(running) {
            coletor->reloadTouchPlugin();
            usleep(500000);
        }
        this->deleteLater();
        LOGD("END");
    }

private:
    ColetorPCP *coletor;
    bool running;
};

#endif // COLETORPCP_H
